home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / egem_200.lzh / EGEM.2_0 / SOURCE / POPUP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-07  |  8.7 KB  |  413 lines

  1.  
  2. #include "proto.h"
  3.  
  4. static int        ob_next(OBJECT *,int);
  5. static int         ob_find(OBJECT *,int,int);
  6. static int        do_popup(OBJECT *,boolean,int,int *);
  7.  
  8. #ifdef DEBUG
  9. extern void _check_hotkeys(OBJECT *);
  10. #endif
  11.  
  12. static int ob_next(OBJECT *tree,int start)
  13. {
  14.     reg OBJECT *obj;
  15.     reg int i = start;
  16.  
  17.     if (start<tree->ob_head)
  18.         start = tree->ob_head;
  19.  
  20.     do
  21.     {
  22.         obj = tree + i;
  23.         if ((obj->ob_state & DISABLED)==0 && (obj->ob_flags & (SELECTABLE|HIDETREE))==SELECTABLE)
  24.             return(i);
  25.         i = obj->ob_next;
  26.     }
  27.     while (i>=0);
  28.  
  29.     return(FAIL);
  30. }
  31.  
  32. static int ob_find(OBJECT *tree,int x,int y)
  33. {
  34.     reg int pos = objc_find(tree,ROOT,1,x,y);
  35.  
  36.     if (pos>0 && ob_next(tree,pos)==pos)
  37.         return(pos);
  38.     else
  39.         return(FAIL);
  40. }
  41.  
  42. static int do_popup(OBJECT *menu,boolean wrap,int last,int *dc)
  43. {
  44.     reg int current,old = FAIL,ret = FAIL;
  45.     XEVENT events;
  46.  
  47.     _mouse_pos(&events.ev_mmox,&events.ev_mmoy);
  48.     if ((current = ob_find(menu,events.ev_mmox,events.ev_mmoy))<=0)
  49.         current = last;
  50.  
  51.     events.ev_mflags = MU_BUTTON|MU_M1|MU_KEYBD;
  52.     events.ev_mbstate = events.ev_mbclicks = events.ev_bmask = 1;
  53.  
  54.     for (;;)
  55.     {
  56.         if (current!=old)
  57.         {
  58.             if (old>0)
  59.                 objc_change(menu,old,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,menu[old].ob_state & (~SELECTED),1);
  60.  
  61.             if (current>0)
  62.                 objc_change(menu,current,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,menu[current].ob_state | SELECTED,1);
  63.  
  64.             old = current;
  65.         }
  66.  
  67.         if (objc_find(menu,ROOT,1,events.ev_mmox,events.ev_mmoy)<0)
  68.         {
  69.             events.ev_mm1flags = 0;
  70.             *(GRECT *) &events.ev_mm1x = *(GRECT *) &menu->ob_x;
  71.         }
  72.         else
  73.         {
  74.             events.ev_mm1flags = events.ev_mm1width = events.ev_mm1height = 1;
  75.             events.ev_mm1x = events.ev_mmox;
  76.             events.ev_mm1y = events.ev_mmoy;
  77.         }
  78.  
  79.         Event_Multi(&events);
  80.         if (events.ev_mwich & MU_BUTTON)
  81.         {
  82.             if (!(events.ev_mmobutton & 1))
  83.             {
  84.                 ret = ob_find(menu,events.ev_mmox,events.ev_mmoy);
  85.                 break;
  86.             }
  87.             else
  88.                 events.ev_mbstate = 0;
  89.         }
  90.  
  91.         if (events.ev_mwich & MU_M1)
  92.         {
  93.             current = ob_find(menu,events.ev_mmox,events.ev_mmoy);
  94.             events.ev_mm2x = events.ev_mmox;
  95.             events.ev_mm2y = events.ev_mmoy;
  96.         }
  97.  
  98.         if (events.ev_mwich & MU_KEYBD)
  99.         {
  100.             int exitmode = FALSE;
  101.  
  102.             switch (events.ev_mkreturn & 0x00ff)
  103.             {
  104.             case 13:
  105.             case 32:
  106.                 ret = current;
  107.                 exitmode = TRUE;
  108.                 break;
  109.             case 27:
  110.                 ret = FAIL;
  111.                 exitmode = TRUE;
  112.             }
  113.  
  114.             if (exitmode==FALSE)
  115.             {
  116.                 switch (events.ev_mkreturn>>8)
  117.                 {
  118.                 case 97:
  119.                     ret = FAIL;
  120.                     exitmode = TRUE;
  121.                     break;
  122.                 case 71:
  123.                     if (events.ev_mmokstate & 3)
  124.                     {
  125.                         reg int j;
  126.  
  127.                         for (j=menu->ob_head;j<=menu->ob_tail;j++)
  128.                             if ((menu[j].ob_state & DISABLED)==0 && (menu[j].ob_flags & (SELECTABLE|HIDETREE))==SELECTABLE)
  129.                                  current = j;
  130.                     }
  131.                     else
  132.                         current = ob_next(menu,menu->ob_head);
  133.                     break;
  134.                 case 75:
  135.                 case 72:
  136.                     {
  137.                         reg int j,temp = FAIL;
  138.  
  139.                         if (current>menu->ob_head)
  140.                         {
  141.                             for (j=menu->ob_head;j<current;j++)
  142.                                 if ((menu[j].ob_state & DISABLED)==0 && (menu[j].ob_flags & (SELECTABLE|HIDETREE))==SELECTABLE)
  143.                                      temp = j;
  144.                         }
  145.  
  146.                         if (temp<0 && (wrap || current<0))
  147.                         {
  148.                             for (j=menu->ob_head;j<=menu->ob_tail;j++)
  149.                                 if ((menu[j].ob_state & DISABLED)==0 && (menu[j].ob_flags & (SELECTABLE|HIDETREE))==SELECTABLE)
  150.                                      temp = j;
  151.                         }
  152.  
  153.                         if (temp>0)
  154.                             current = temp;
  155.                     }
  156.                     break;
  157.                 case 77:
  158.                 case 80:
  159.                     if (current<menu->ob_tail)
  160.                     {
  161.                         if (current<0)
  162.                             current = ob_next(menu,menu->ob_head);
  163.                         else
  164.                         {
  165.                             int temp = ob_next(menu,menu[current].ob_next);
  166.                             if (temp>0 && temp!=current)
  167.                                 current = temp;
  168.                             else
  169.                                 current = ob_next(menu,menu->ob_head);
  170.                         }
  171.                     }
  172.                     else if (wrap)
  173.                         current = ob_next(menu,menu->ob_head);
  174.                     break;
  175.                 default:
  176.                     {
  177.                         int obj;
  178.  
  179.                         if ((obj=_is_hotkey(menu,scan_2_ascii(events.ev_mkreturn,events.ev_mmokstate)))>0)
  180.                         {
  181.                             if ((menu[obj].ob_state & DISABLED)==0 && (menu[obj].ob_flags & (SELECTABLE|HIDETREE))==SELECTABLE)
  182.                             {
  183.                                 if (old>0)
  184.                                     objc_change(menu,old,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,menu[old].ob_state & (~SELECTED),1);
  185.                                 objc_change(menu,obj,0,desk.g_x,desk.g_y,desk.g_w,desk.g_h,menu[obj].ob_state | SELECTED,1);
  186.                                 Event_Timer(100,0);
  187.  
  188.                                 exitmode = TRUE;
  189.                                 ret = obj;
  190.                             }
  191.                         }
  192.                     }
  193.                 }
  194.             }
  195.  
  196.             if (exitmode)
  197.                 break;
  198.         }
  199.     }
  200.  
  201.     if (ret>0)
  202.         *dc = (events.ev_mbreturn>=2 || (events.ev_mmokstate & 3));
  203.     return (ret);
  204. }
  205.  
  206. int Popup(POPUP *popup,int mode,int center,int x,int y,int *index,int select)
  207. {
  208.     reg DIAINFO *info = popup->p_info;
  209.     reg OBJECT *menu = popup->p_menu,*tree=(info!=NULL) ? info->di_tree : NULL;
  210.     reg int current = FAIL,exit = FAIL,object;
  211.     int dc = FALSE;
  212.  
  213.     graf_mouse(ARROW,NULL);
  214.  
  215.     if (tree!=NULL)
  216.     {
  217.         object = (mode & POPUP_CYCLE) ? popup->p_cycle : popup->p_parent;
  218.         if (object>0)
  219.             ob_draw_chg(info,object,NULL,tree[object].ob_state|SELECTED,FALSE);
  220.     }
  221.  
  222.     {
  223.         reg int i;
  224.  
  225.         for (i=menu->ob_head;i<=menu->ob_tail;i++)
  226.         {
  227.             if (menu[i].ob_flags & SELECTABLE)
  228.                 menu[i].ob_state &= ~SELECTED;
  229.  
  230.             if (!(menu[i].ob_flags & HIDETREE))
  231.             {
  232.                 if (i==select)
  233.                 {
  234.                     if (mode & POPUP_CHECK)
  235.                         menu[i].ob_state |= CHECKED;
  236.                     if (current>=0)
  237.                         menu[current].ob_state &= ~CHECKED;
  238.                     current=i;
  239.                 }
  240.                 else if (menu[i].ob_state & CHECKED)
  241.                 {
  242.                     if (!(mode & POPUP_CHECK) || current>=0)
  243.                         menu[i].ob_state &= ~CHECKED;
  244.                     else
  245.                         current = i;
  246.                 }
  247.             }
  248.         }
  249.     }
  250.  
  251.     if (!(mode & POPUP_CYCLE))
  252.     {
  253.         int sx,sy,sw = menu->ob_width>>1,sh = menu->ob_height>>1,dummy;
  254.         long mem = 0l;
  255.         MFDB dial;
  256.  
  257.         _mouse_pos(&sx,&sy);
  258.         if (tree!=NULL && popup->p_button>0)
  259.         {
  260.             int bx,by;
  261.             objc_offset(tree,popup->p_button,&bx,&by);
  262.             if (x<=0)
  263.                 x = bx;
  264.             if (y<=0)
  265.                 y = by;
  266.         }
  267.  
  268.         switch (center)
  269.         {
  270.         case CENTER:
  271.             {
  272.                 INFOVSCR *vscr;
  273.  
  274.                 form_center(menu,&dummy,&dummy,&dummy,&dummy);
  275.                 if (get_cookie(COOKIE_VSCR,(long *) &vscr) && (vscr->cookie==COOKIE_XBRA))
  276.                 {
  277.                     menu->ob_x = vscr->x + (vscr->w>>1) - sw;
  278.                     menu->ob_y = vscr->y + (vscr->h>>1) - sh;
  279.                 }
  280.             }
  281.             break;
  282.         case XYPOS:
  283.             menu->ob_x = x;
  284.             menu->ob_y = y;
  285.             break;
  286.         case MOUSEPOS:
  287.             menu->ob_x = sx - sw;
  288.             menu->ob_y = sy - sh;
  289.             break;
  290.         case XPOS:
  291.             menu->ob_x = x;
  292.             menu->ob_y = sy - sh;
  293.             break;
  294.         case YPOS:
  295.             menu->ob_x = sx - sw;
  296.             menu->ob_y = y;
  297.             break;
  298.         case OBJPOS:
  299.             menu->ob_x = x;
  300.             menu->ob_y = y;
  301.             if (current>=0)
  302.             {
  303.                 menu->ob_x -= menu[current].ob_x;
  304.                 menu->ob_y -= menu[current].ob_y;
  305.             }
  306.         }
  307.  
  308.         Min(&menu->ob_x,clip.v_x2 - menu->ob_width - 3);
  309.         Max(&menu->ob_x,clip.v_x1 + 3);
  310.         Min(&menu->ob_y,clip.v_y2 - menu->ob_height - 3);
  311.         Max(&menu->ob_y,clip.v_y1 + 3);
  312.  
  313.         sx = menu->ob_x - 3;
  314.         sy = menu->ob_y - 3;
  315.         sw = menu->ob_width + 6;
  316.         sh = menu->ob_height + 6;
  317.  
  318.         _beg_ctrl();
  319.         mfdb(&dial,NULL,sw,sh,0,planes);
  320.  
  321.         {
  322.             reg long len = mfdb_size(&dial);
  323.  
  324.             if ((long) Malloc(-1l)>(len+4096l))
  325.             {
  326.                 if ((mem = (long) Malloc(len+256l))>0l)
  327.                 {
  328.                     dial.fd_addr    = (int *) ((mem & 0xfffffffel) + 2);
  329.                     _bitblt(menu,&dial,TRUE);
  330.                     goto draw_popup;
  331.                 }
  332.             }
  333.         }
  334.  
  335.         form_dial(FMD_START,sx,sy,sw,sh,sx,sy,sw,sh);
  336.  
  337.         draw_popup:
  338.         objc_draw(menu,ROOT,MAX_DEPTH,sx,sy,sw,sh);
  339.  
  340.     #ifdef DEBUG
  341.         check_hotkeys(menu);
  342.     #endif
  343.  
  344.         _popup++;
  345.         exit = do_popup(menu,popup->p_wrap,current,&dc);
  346.         _popup--;
  347.  
  348.         if (mem)
  349.         {
  350.             _bitblt(menu,&dial,FALSE);
  351.             Mfree((void *) mem);
  352.         }
  353.         else
  354.             form_dial(FMD_FINISH,sx,sy,sw,sh,sx,sy,sw,sh);
  355.         _end_ctrl();
  356.     }
  357.     else
  358.     {
  359.         if (current<0 || current>=menu->ob_tail)
  360.             exit = ob_next(menu,menu->ob_head);
  361.         else
  362.         {
  363.             int temp = ob_next(menu,menu[current].ob_next);
  364.             exit = (temp>0) ? temp : ob_next(menu,menu->ob_head);
  365.         }
  366.     }
  367.  
  368.     if (tree!=NULL && object>0)
  369.         ob_draw_chg(info,object,NULL,tree[object].ob_state & (~SELECTED),FALSE);
  370.  
  371.     if (exit>0)
  372.     {
  373.         if (mode & POPUP_CHECK)
  374.         {
  375.             if (current>=0)
  376.                 menu[current].ob_state &= ~CHECKED;
  377.             menu[exit].ob_state |= CHECKED;
  378.         }
  379.  
  380.         if (tree!=NULL && popup->p_set && popup->p_button>0)
  381.         {
  382.             ob_set_text(tree,popup->p_button,ob_get_text(menu,exit,0));
  383.             ob_draw_chg(info,popup->p_button,NULL,FAIL,FALSE);
  384.             if (popup->p_cycle>0)
  385.                 ob_draw_chg(info,popup->p_cycle,NULL,FAIL,FALSE);
  386.         }
  387.  
  388.         if (index!=NULL)
  389.         {
  390.             reg int i = 1,radio = 0;
  391.  
  392.             do
  393.             {
  394.                 if ((menu[i].ob_flags & (SELECTABLE|HIDETREE))==SELECTABLE)
  395.                 {
  396.                     if (i==exit)
  397.                     {
  398.                         *index = radio;
  399.                         break;
  400.                     }
  401.                     radio++;
  402.                 }
  403.                 i = menu[i].ob_next;
  404.             } while (i>=0);
  405.         }
  406.     }
  407.  
  408.     if (exit<=0)
  409.         return(0);
  410.     else
  411.         return ((dc) ? (exit|0x8000) : exit);
  412. }
  413.